﻿using ajayumi.develop.win32.Transport.Core;
using ajayumi.develop.win32.Transport.Utils;
using ajayumi.develop.win32.Transport.Utils.WinForm;
using ajayumi.develop.win32.Transport.WCF.Services;
using System;
using System.Collections.Generic;
using System.IO;
using System.ServiceModel;
using System.Threading;
using System.Windows.Forms;

namespace ajayumi.develop.win32.Transport.Client.WinForm.Controls
{
    public partial class UcDownload : UserControl
    {
        #region Variables

        #endregion

        public Action<string> Display { get; set; }

        public UcDownload()
        {
            InitializeComponent();

            ControlHelper.DoubleBuffered(this.dgvDownloadFiles, true);
            this.dgvDownloadFiles.AutoGenerateColumns = false;
            this.dgvDownloadFiles.DataSource = TransTaskManager.Instance.DownloadFileCollection;
        }

        private void RaiseDisplay(string text)
        {
            if (this.Display != null)
            { this.Display(text); }
        }

        private void InvokeDownloadFile(FilePathInfo[] paths)
        {
            ThreadPool.SetMaxThreads(10, 1000);
            foreach (FilePathInfo item in paths)
            {
                TransportFileServiceClient client = new TransportFileServiceClient();
                DownloadFile downloadFile = new DownloadFile(item.RootPath, item.RelativePath,
                                           (file) => { return client.InitDownloadFile(file); },
                                           (file) => { return client.DownloadFile(file); });
                downloadFile.SaveDirectoryFunc = () => { return AppConfig.SaveDir; };
                downloadFile.TransReady += (sender, e) =>
                {
                    TransTaskManager.Instance.DownloadFileCollection.TransFileReady(e.RelativePath,
                        FileHelper.FormatFileSize(e.FileLength),
                        e.ProgressPercentage);
                };
                downloadFile.TransProgressChanged += (sender, e) =>
                {
                    TransTaskManager.Instance.DownloadFileCollection.TransFileProgressChanged(e.RelativePath, e.ProgressPercentage);
                    this.RaiseDisplay(string.Format("{0} {1} 下载进度：{2}%.\r\n", DateTime.Now, e.RelativePath, e.ProgressPercentage));
                };
                downloadFile.TransCompleted += (sender, e) =>
                {
                    TransTaskManager.Instance.DownloadFileCollection.TransFileCompleted(e);

                    if (e.Error != null)
                    {
                        this.RaiseDisplay(string.Format("{0} {1} 下载时发生错误。错误信息：\r\n{2}\r\n", DateTime.Now, e.RelativePath, e.Error.Message));
                    }
                    else
                    {
                        this.RaiseDisplay(string.Format("{0} {1} 下载完毕.\r\n", DateTime.Now, e.RelativePath));
                    }

                    try
                    {
                        client.Close();
                    }
                    catch (FaultException ex)
                    {
                        client.Abort();
                        this.RaiseDisplay(string.Format("{0} {1} 下载时发生错误。错误信息：\r\n{2}\r\n", DateTime.Now, e.RelativePath, ex.Message));
                    }
                    catch (TimeoutException ex)
                    {
                        client.Abort();
                        this.RaiseDisplay(string.Format("{0} {1} 下载时发生错误。错误信息：\r\n{2}\r\n", DateTime.Now, e.RelativePath, ex.Message));
                    }
                    catch (Exception ex)
                    {
                        client.Abort();
                        this.RaiseDisplay(string.Format("{0} {1} 下载时发生错误。错误信息：\r\n{2}\r\n", DateTime.Now, e.RelativePath, ex.Message));
                    }
                };


                TransFileItem transFileItem = new TransFileItem()
                {
                    Name = Path.GetFileName(item.RelativePath),
                    RelativePath = item.RelativePath
                };
                this.dgvDownloadFiles.Invoke(new Action<TransFileItem>(TransTaskManager.Instance.DownloadFileCollection.Add),
                    new object[] { transFileItem });

                ThreadPool.QueueUserWorkItem(new WaitCallback(downloadFile.RunWork), item);
            }
        }

        private void tsbtnDownload_Click(object sender, EventArgs e)
        {
            using (FolderBrowserDlg dlg = new FolderBrowserDlg())
            {
                if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    string path = dlg.SelectedPath;
                    if (string.IsNullOrEmpty(path)) return;
                    List<FilePathInfo> lst = null;

                    if (dlg.IsDirectory)
                    {
                        lst = dlg.DriveNodeList;
                    }
                    else
                    {
                        lst = new List<FilePathInfo>();
                        lst.Add(new FilePathInfo()
                        {
                            RootPath = Path.GetDirectoryName(path),
                            RelativePath = Path.GetFileName(path)
                        });
                    }

                    this.InvokeDownloadFile(lst.ToArray());
                }
            }
        }

        private void tsbtnClearDownloadCmp_Click(object sender, EventArgs e)
        {
            TransTaskManager.Instance.DownloadFileCollection.ClearCompleted();
        }
    }
}
